/**
 * @description 作品 数据操作
 */

const _ = require('lodash')
const { WorkContentModel, WorkPublishContentModel } = require('../model/workContent')
const WorksModel = require('../model/work')
const { DEFAULT_PAGE_SIZE } = require('../config/constant')

const defaultPageCondition = {
  pageIndex: 0,
  pageSize: DEFAULT_PAGE_SIZE
}

/**
 * 创建作品
 * @param {object} data 作品数据
 * @param {object} content 作品内容
 */
async function createWork(data = {}, content = {}) {
  const { components = [], props = {}, setting = {} } = content
  // 创建作品内容
  const newContent = await WorkContentModel.create({
    // 符合 WorkContentModel 属性规则
    components,
    props,
    setting
  })
  const { _id: contentId } = newContent
  // 创建作品记录
  const newWork = await WorksModel.create({
    ...data,
    contentId
  })

  return newWork
}

/**
 * 查询单个作品
 * @param {object} whereOpt 查询条件
 */
async function findOneWork(whereOpt = {}) {
  if (_.isEmpty(whereOpt)) return null // 无查询条件
  const populate = { path: 'user', select: 'username nickName picture' }
  const work = await WorksModel.findOne(whereOpt).populate(populate).lean()
  if (work) {
    const { contentId } = work
    const content = await WorkContentModel.findById(contentId)
    return {
      ...work,
      content
    }
  }
  return null
}

/**
 * 更新作品数据
 * @param {object} data 要更新的数据
 * @param {object} whereOpt 查询提交件
 * @returns {Promise<boolean>} true/false
 */
async function updateWork(data = {}, whereOpt = {}) {
  // 保证数据不为空
  if (_.isEmpty(data)) return false
  if (_.isEmpty(whereOpt)) return false
  // 要更新的数据
  const updateData = data
  const { content } = updateData
  // 如果需要更新 content
  if (content) {
    const workData = await findOneWork(whereOpt)
    if (!workData) {
      return false
    }
    const { contentId } = workData
    await WorkContentModel.findByIdAndUpdate(contentId, {
      components: content.components || [],
      props: content.props || {},
      setting: content.setting || {}
    })
    // 删除不需要更新的数据
    delete updateData.content
    delete updateData.contentId
    if (_.isEmpty(updateData)) {
      // 例如用户只更新 content
      return true
    }
  }
  const result = await WorksModel.findOneAndUpdate(whereOpt, updateData, { new: true })
  return !!result
}

/**
 * 查询 作品/模板 列表
 * @param {object} whereOpt 查询条件
 * @param {object} pageOpt 分页数据
 */
async function findWorkList(whereOpt = {}, pageOpt = {}) {
  const select = 'id author copiedCount coverImg desc title user isHot createdAt status'
  const populate = { path: 'user', select: 'username nickName picture' }
  const pageCondition = { ...defaultPageCondition, ...pageOpt }
  const { pageSize, pageIndex } = pageCondition
  const skip = pageIndex * pageSize

  const result = await WorksModel.find(whereOpt)
    .select(select) // 查询的字段
    .populate(populate) // 查询作品记录  populate 关联哪些集合以及返回哪些值
    .skip(skip) // 跳过多少条
    .limit(pageSize) // 每页多少条
    .sort({ createdAt: -1 }) // 倒序
    .lean() // 直接返回 object 对象，不需要返回 Document 类型的对象，加快查询速度

  const count = await WorksModel.find(whereOpt).count()

  return {
    count,
    list: result,
    pageSize,
    pageIndex
  }
}

/**
 * 更新发布内容
 * @param {object} content 作品内容
 * @param {string} publishContentId 发布内容 id
 * @returns {Promise<string | null>} publishContentId
 */
async function updatePublishContent(content, publishContentId) {
  if (!content) return null

  const { components = [], props = {}, setting = {} } = content

  // 已有发布内容 id 则更新
  if (publishContentId) {
    await WorkPublishContentModel.findByIdAndUpdate(publishContentId, {
      components,
      props,
      setting
    })
    return publishContentId
  }

  // 还没有发布内容 id，则创建
  const newPublishContent = await WorkPublishContentModel.create({
    components,
    props,
    setting
  })
  return newPublishContent._id
}

module.exports = {
  createWork,
  findOneWork,
  updateWork,
  findWorkList,
  updatePublishContent
}
